﻿using System;
using System.Collections.Generic;
using Opalis.QuickIntegrationKit;
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Exchange.WebServices.Autodiscover;
using System.Text;
using System.Net;
using System.Threading;

namespace ExchangeMail
{
    [OpalisObject("Monitor Mailbox"), OpalisMonitor()]
    public class MonitorMailbox : IOpalisObject
    {
        private MailboxSettings settings;
        private String exchangeVersion = String.Empty;
        private String userName = String.Empty;
        private String password = String.Empty;
        private String domain = String.Empty;
        private String folderName = String.Empty;
        private int MonitorInterval = 60;
        private FolderId folderID = new FolderId(WellKnownFolderName.Inbox);
        private String serviceURL = String.Empty;

        [OpalisConfiguration]
        public MailboxSettings Settings
        {
            get { return settings; }
            set { settings = value; }
        }


        public void Design(IOpalisDesigner designer)
        {
            designer.AddInput("Folder Name").WithDefaultValue("Inbox");
            designer.AddInput("Monitor Interval [Seconds]").WithDefaultValue(60);
            designer.AddCorellatedData(typeof(Email));
        }

        public void Execute(IOpalisRequest request, IOpalisResponse response)
        {
            userName = settings.UserName;
            password = settings.Password;
            domain = settings.Domain;
            serviceURL = settings.ServiceUrl;
            exchangeVersion = settings.ExchangeVersion;

            folderName = request.Inputs["Folder Name"].AsString();
            MonitorInterval = request.Inputs["Monitor Interval [Seconds]"].AsInt32();
            
            response.WithFiltering().PublishRange(getMail());
        }

        private IEnumerable<Email> getMail()
        {
            DateTime StartTime = DateTime.Now;
            Boolean complete = false;

            ExchangeService service = new ExchangeService();
            switch (exchangeVersion)
            {
                case "Exchange2007_SP1":
                    service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
                    break;
                case "Exchange2010":
                    service = new ExchangeService(ExchangeVersion.Exchange2010);
                    break;
                case "Exchange2010_SP1":
                    service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
                    break;
                default:
                    service = new ExchangeService();
                    break;
            }

            service.Credentials = new WebCredentials(userName, password, domain);
            String AccountUrl = userName + "@" + domain;

            if (serviceURL.Equals("Autodiscover")) { service.AutodiscoverUrl(AccountUrl); }
            else { service.Url = new Uri(serviceURL); }


            if (!folderName.Equals(String.Empty))
            {
                SearchFilter filter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, folderName);
                FolderView view = new FolderView(int.MaxValue);
                view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
                view.PropertySet.Add(FolderSchema.DisplayName);
                view.Traversal = FolderTraversal.Deep;
                FindFoldersResults results = service.FindFolders(WellKnownFolderName.MsgFolderRoot, filter, view);

                foreach (Folder folder in results)
                {
                    folderID = folder.Id;
                    break;
                }
            }

            while(!complete)
            {
                Thread.Sleep(TimeSpan.FromSeconds(Convert.ToDouble(MonitorInterval)));
                SearchFilter filter = new SearchFilter.IsGreaterThanOrEqualTo(EmailMessageSchema.LastModifiedTime,StartTime);
                FindItemsResults<Item> findResults = service.FindItems(folderID, filter, new ItemView(int.MaxValue));
                
                foreach (EmailMessage item in findResults.Items)
                {
                    if (item.GetType().ToString().Equals("Microsoft.Exchange.WebServices.Data.EmailMessage"))
                    {
                        EmailMessage message = EmailMessage.Bind(service, item.Id);
                        String body = message.Body.ToString();
                        String from = message.From.Address.ToString();
                        String subject = message.Subject.ToString();
                        String id = item.Id.ToString();
                        DateTime recievedDate = message.DateTimeReceived;
                        Boolean Attachments = message.HasAttachments;

                        complete = true;
                        yield return new Email(subject, body, from, id, recievedDate, Attachments);
                    }
                }
            }
        }
    }
}
